package com.mtw.bbs.fileAdmin.controller;



import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mtw.bbs.common.core.vo.Result;
import com.mtw.bbs.fileAdmin.pojo.entity.FileEntity;
import com.mtw.bbs.fileAdmin.pojo.form.FileUploadForm;
import com.mtw.bbs.fileAdmin.exception.FileBusException;
import com.mtw.bbs.fileAdmin.pojo.vo.FileVo;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.mtw.bbs.fileAdmin.service.FileService;

import java.util.List;

/**
 * 文件上传接口层
 */
@Slf4j
@RestController
@RequestMapping("file")
@RequiredArgsConstructor
public class FileController {


    private final FileService fileService;



    @PostMapping(value = "/upload")
    @ApiOperation(value = "文件上传")
    public Result<FileVo> facilityUpload(@RequestParam("md5") String md5,
                                         @RequestParam("file") MultipartFile file) {

        FileVo vo;
        try {
            FileUploadForm form = new FileUploadForm();
            form.setFile(file);
            form.setMd5(md5);
            log.info("开始上传文件，文件MD5：{}",form.getMd5());
            String id = fileService.uploadFile(form);
            vo = fileService.getFileUrl(id);
        }catch (FileBusException e){
            log.error("上传文件失败，文件MD5：{}",md5,e);
            return Result.fail(e.getMessage());
        }
        return Result.success(vo);
    }


    @GetMapping(value = "/check")
    @ApiOperation(value = "文件上传前检查")
    public Result<FileVo> check(@RequestParam("md5") String md5) {

        LambdaQueryWrapper<FileEntity> lqw = new LambdaQueryWrapper<>();
        lqw.select(FileEntity::getId);
        lqw.eq(FileEntity::getMd5,md5);
        List<FileEntity> savedList = fileService.list(lqw);
        log.info("文件上传前检查文件，文件MD5：{}，查询到数据：{}",md5,savedList.size());
        if (!CollectionUtils.isEmpty(savedList)){
            FileVo vo = fileService.getFileUrl(savedList.get(0).getId());
            return Result.success(vo);
        }
        return Result.success();
    }



    @GetMapping(value = "/shardCheck")
    @ApiOperation(value = "分片文件上传前检查，返回当前应上传片索引")
    public Result<Integer> shardCheck(@RequestParam("md5") String md5) {

        Integer index = fileService.shardCheck(md5);
        return Result.success(index);
    }


    /**
     * 文件上传，适合大文件，集成了分片上传
     */
    @PostMapping(value = "/shardUpload")
    @ApiOperation(value = "分片文件上传")
    public Result shardUpload(@RequestParam("shardCount") Integer shardCount,
                              @RequestParam("index") Integer index,
                              @RequestParam("md5") String md5,
                              @RequestParam("name") String name,
                              @RequestParam("fileSize") Long fileSize,
                              @RequestParam("file") MultipartFile file) {

        try {
            FileUploadForm dto = new FileUploadForm();
            dto.setFile(file);
            dto.setMd5(md5);
            dto.setName(name);
            dto.setShardCount(shardCount);
            dto.setIndex(index);
            dto.setFileSize(fileSize);
            fileService.uploadFileByShard(dto);
        }catch (Exception e){
            log.error("分片上传异常：md5：{}，文件大小：{}",md5,fileSize,e);
            return Result.fail(e.getMessage());
        }
        return Result.success();

    }





    /**
     * 文件合并
     * @return 分片合并的状态
     */
    @PostMapping(value = "/merge")
    public Result<FileVo> merge(@RequestBody FileUploadForm dto) {


        FileVo vo;
        try {
            vo = fileService.mergeFile(dto);
        }catch (FileBusException e){
            return Result.fail(e.getMessage());
        }
        return Result.success(vo);
    }


}
